#include "Driver_Uart.h"
#include "Driver_Delay.h"
#include "Task.h"
#include <stdio.h>
#include <string.h>

uint32_t ModuleID;
uint8_t Mac_Buff[13];
uint8_t IP_Buff[5];

uint8_t Package_Data[64] = {0x28, 0x41, 0x50, 0x54, 0x45, 0x53, 0x54, 0x29,
                            0x28, 0x41, 0x50, 0x54, 0x45, 0x53, 0x54, 0x29,
                            0x28, 0x41, 0x50, 0x54, 0x45, 0x53, 0x54, 0x29,
                            0x28, 0x41, 0x50, 0x54, 0x45, 0x53, 0x54, 0x29,
                            0x28, 0x41, 0x50, 0x54, 0x45, 0x53, 0x54, 0x29,
                            0x28, 0x41, 0x50, 0x54, 0x45, 0x53, 0x54, 0x29,
                            0x28, 0x41, 0x50, 0x54, 0x45, 0x53, 0x54, 0x29,
                            0x28, 0x41, 0x50, 0x54, 0x45, 0x53, 0x54, 0x29};

uart_txbuff_t Uart_TxBuff;
uart_buff_t Uart_RxBuff;

void ComPort_Uart_Init_Fuc(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

  USART_DeInit(USART1);
  USART_StructInit(&USART_InitStructure);
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  USART_Init(USART1, &USART_InitStructure);

  DMA_DeInit(DMA1_Channel2);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->TDR;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Uart_TxBuff;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = 0;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel2, &DMA_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  USART_Cmd(USART1, ENABLE);

  USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
  DMA_ClearFlag(DMA1_FLAG_TC1);
  DMA_ClearFlag(DMA1_FLAG_TE1);
  DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);
  DMA_ITConfig(DMA1_Channel2, DMA_IT_TE, ENABLE);
  DMA_Cmd(DMA1_Channel2, DISABLE);

  Cbuf_Init(Uart_RxBuff);
}

void ComPort_Uart_Deinit_Fuc(void)
{
  USART_DeInit(USART1);
  USART_ITConfig(USART1, USART_IT_TXE | USART_IT_RXNE, DISABLE);
  USART_Cmd(USART1, DISABLE);
}

void USART1_IRQHandler(void)
{
  char c;
  uint32_t status = USART1->ISR;

  if (status & USART_ISR_RXNE)
  {
    c = (uint16_t)(USART1->RDR & (uint16_t)0x01FF);
    Cbuf_Push(Uart_RxBuff, c);
  }
  else if (status & USART_ISR_ORE)
  {
    c = (uint16_t)(USART1->RDR & (uint16_t)0x01FF);
    USART1->ICR = USART_ICR_ORECF;
  }
}

uint16_t Uart_Rx_GetLen(void)
{
  return Cbuf_Len(Uart_RxBuff);
}

uint8_t Uart_Rx_GetByte(void)
{
  return (Cbuf_IsEmpty(Uart_RxBuff) ? EOF : Cbuf_Pop(Uart_RxBuff));
}

void Communication_Handler(void) // 任务自己添加
{
  static uint8_t status = 0, decode = 0;
  uint16_t bytes = 0;
  uint8_t c = 0;

  switch (status)
  {
  case AP_SET1: // 给模块连续发送‘+++’直到模块回复‘A’
    User_Bytes_Sender("+++");
    status = AP_SET1_ACK;
    break;
  case AP_SET1_ACK: // 检查接收缓存区，)查看是否恢复正确的回复字
    bytes = Uart_Rx_GetLen();
    status = AP_SET1;
    for (uint8_t i = 0; i < bytes; i++)
    {
      if (0x61 == Uart_Rx_GetByte()) //收到"A",清空接收缓存区
      {
        Cbuf_Init(Uart_RxBuff);
        status = AP_SET2;
      }
    }
    break;
  case AP_SET2:
    User_Bytes_Sender("a"); // 设备端接收到‘A’，给模块端发送‘A’，等待应答'+OK'
    status = AP_SET2_ACK;
    break;
  case AP_SET2_ACK: // 检查接收缓存区，查看是否恢复正确的回复字
    bytes = Uart_Rx_GetLen();
    status = AP_SET1;
    decode = 0x00;
    for (uint8_t i = 0; i < bytes; i++)
    {
      c = Uart_Rx_GetByte();
      switch (decode)
      {
      case 0x00:
        if (c == 0x2B)
        {
          decode = 0x01;
        }
        break;
      case 0x01:
        if (c == 0x4F)
        {
          decode = 0x02;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x02:
        if (c == 0x4B)
        {
          status = AP_WSTA;
          Cbuf_Init(Uart_RxBuff);
        }
        else
        {
          decode = 0x00;
        }
        break;
      }
    }
    break;
  case AP_WSTA:
    User_Bytes_Sender("AT+WSTA=Heenway,12345687\r\n"); // 发送AT指令设置AP名称和密码
    status = AP_WSTA_ACK;
    break;
  case AP_WSTA_ACK: // 检查接收缓存区，查看是否恢复正确的回复字
    bytes = Uart_Rx_GetLen();
    status = AP_WSTA;
    decode = 0x00;
    for (uint8_t i = 0; i < bytes; i++)
    {
      c = Uart_Rx_GetByte();
      switch (decode)
      {
      case 0x00:
        if (c == 0x2B)
        {
          decode = 0x01;
        }
        break;
      case 0x01:
        if (c == 0x4F)
        {
          decode = 0x02;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x02:
        if (c == 0x4B)
        {
          status = AP_WANN;
          Cbuf_Init(Uart_RxBuff);
        }
        else
        {
          decode = 0x00;
        }
        break;
      }
    }
    break;
  case AP_WANN:
    User_Bytes_Sender("AT+WANN\r\n"); // 发送AT指令设置AP名称和密码
    status = AP_WANN_ACK;
    break;
  case AP_WANN_ACK: // 检查接收缓存区，查看是否恢复正确的回复字
    bytes = Uart_Rx_GetLen();
    status = AP_WANN;
    decode = 0x00;
    for (uint8_t i = 0; i < bytes; i++)
    {
      c = Uart_Rx_GetByte();
      switch (decode)
      {
      case 0x00:
        if (c == 0x2B)
        {
          decode = 0x01;
        }
        break;
      case 0x01:
        if (c == 0x4F)
        {
          decode = 0x02;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x02:
        if (c == 0x4B)
        {
          decode = 0x03;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x03:
        if (c == 0x3D)
        {
          decode = 0x04;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x04:
        if (c == 0x2C)
        {
          decode = 0x05;
          IP_Buff[0] = 1;
          IP_Buff[1] = 0;
          IP_Buff[2] = 0;
          IP_Buff[3] = 0;
          IP_Buff[4] = 0;
        }
        break;
      case 0x05:
        if (c != 0x2E)
        {
          IP_Buff[IP_Buff[0]] = IP_Buff[IP_Buff[0]] * 10 + c;
        }
        else
        {
          if (IP_Buff[0] < 4)
          {
            IP_Buff[0]++;
          }
          else
          {
            decode = 0x00;
            status = AP_SOCKA;
            Cbuf_Init(Uart_RxBuff);
          }
        }
        break;
      }
    }
    break;
  case AP_SOCKA:
    User_Bytes_Sender("AT+SOCKA=TCPC,192.168.1.133,20000\r\n"); // 发送AT指令设置AP名称和密码
    status = AP_SOCKA_ACK;
    break;
  case AP_SOCKA_ACK: // 检查接收缓存区，查看是否恢复正确的回复字
    bytes = Uart_Rx_GetLen();
    status = AP_SOCKA;
    decode = 0x00;
    for (uint8_t i = 0; i < bytes; i++)
    {
      c = Uart_Rx_GetByte();
      switch (decode)
      {
      case 0x00:
        if (c == 0x2B)
        {
          decode = 0x01;
        }
        break;
      case 0x01:
        if (c == 0x4F)
        {
          decode = 0x02;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x02:
        if (c == 0x4B)
        {
          status = AP_SOCKLKA;
          Cbuf_Init(Uart_RxBuff);
        }
        else
        {
          decode = 0x00;
        }
        break;
      }
    }
    break;
  case AP_SOCKLKA:
    User_Bytes_Sender("AT+SOCKLKA\r\n"); // 检查WiFi模块是否连接成功
    status = AP_SOCKLKA_ACK;
    break;
  case AP_SOCKLKA_ACK:
    bytes = Uart_Rx_GetLen();
    status = AP_SOCKLKA;
    decode = 0x00;
    for (uint8_t i = 0; i < bytes; i++)
    {
      c = Uart_Rx_GetByte();
      switch (decode)
      {
      case 0x00:
        if (c == 0x2B)
        {
          decode = 0x01;
        }
        break;
      case 0x01:
        if (c == 0x4F)
        {
          decode = 0x02;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x02:
        if (c == 0x4B)
        {
          decode = 0x03;
        }
        break;
      case 0x03:
        if (c == 0x3D)
        {
          decode = 0x04;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x04:
        if (c == 0x44) // DISCONNECTED
        {
          decode = 0x00;
          status = AP_SOCKLKA;
          Cbuf_Init(Uart_RxBuff);
        }
        else if (c == 0x43) // CONNECTED
        {
          decode = 0x00;
          status = AP_ENTM;
          Cbuf_Init(Uart_RxBuff);
          GPIOB->BSRR = GPIO_BSRR_BS_1;
        }
        break;
      }
    }
    break;
  case AP_ENTM:
    User_Bytes_Sender("AT+ENTM\r\n"); // 发送AT指令设置AP名称和密码
    status = AP_ENTM_ACK;
    break;
  case AP_ENTM_ACK: // 检查接收缓存区，查看是否恢复正确的回复字
    bytes = Uart_Rx_GetLen();
    status = AP_ENTM;
    decode = 0x00;
    for (uint8_t i = 0; i < bytes; i++)
    {
      c = Uart_Rx_GetByte();
      switch (decode)
      {
      case 0x00:
        if (c == 0x2B)
        {
          decode = 0x01;
        }
        break;
      case 0x01:
        if (c == 0x4F)
        {
          decode = 0x02;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x02:
        if (c == 0x4B)
        {
          status = AP_PAYLOAD;
          Cbuf_Init(Uart_RxBuff);
          Task_Set_Period(TASK_ID_COMMUNICATION, 1000);
        }
        else
        {
          decode = 0x00;
        }
        break;
      }
    }
    break;
  case AP_PAYLOAD:
    User_Packet_Sender(0, (uint8_t *)&Package_Data, 64); // 传输固定的包
    break;
  default:
    break;
  }
}

void Communication_Test_Handler(void) // 任务自己添加
{
  static uint8_t status = 0, decode = 0;
  uint16_t bytes = 0;
  uint8_t c = 0;

  switch (status)
  {
  case 0x00: // 给模块连续发送‘+++’直到模块回复‘A’
    User_Bytes_Sender("+++");
    status = 0x01;
    break;
  case 0x01: // 检查接收缓存区，)查看是否恢复正确的回复字
    bytes = Uart_Rx_GetLen();
    status = 0x00;
    for (uint8_t i = 0; i < bytes; i++)
    {
      if (0x61 == Uart_Rx_GetByte()) //收到"A",清空接收缓存区
      {
        Cbuf_Init(Uart_RxBuff);
        status = 0x02;
      }
    }
    break;
  case 0x02:
    User_Bytes_Sender("a"); // 设备端接收到‘A’，给模块端发送‘A’，等待应答'+OK'
    status = 0x03;
    break;
  case 0x03: // 检查接收缓存区，查看是否恢复正确的回复字
    bytes = Uart_Rx_GetLen();
    status = 0x00;
    decode = 0x00;
    for (uint8_t i = 0; i < bytes; i++)
    {
      c = Uart_Rx_GetByte();
      switch (decode)
      {
      case 0x00:
        if (c == 0x2B)
        {
          decode = 0x01;
        }
        break;
      case 0x01:
        if (c == 0x4F)
        {
          decode = 0x02;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x02:
        if (c == 0x4B)
        {
          status = 0x04;
          Cbuf_Init(Uart_RxBuff);
        }
        else
        {
          decode = 0x00;
        }
        break;
      }
    }
    break;
  case 0x04:
    User_Bytes_Sender("AT+WMODE=STA\r\n"); // 设置为STA模式
    status = 0x05;
    break;
  case 0x05: // 检查接收缓存区，查看是否恢复正确的回复字
    bytes = Uart_Rx_GetLen();
    status = 0x04;
    decode = 0x00;
    for (uint8_t i = 0; i < bytes; i++)
    {
      c = Uart_Rx_GetByte();
      switch (decode)
      {
      case 0x00:
        if (c == 0x2B)
        {
          decode = 0x01;
        }
        break;
      case 0x01:
        if (c == 0x4F)
        {
          decode = 0x02;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x02:
        if (c == 0x4B)
        {
          status = 0x06;
          Cbuf_Init(Uart_RxBuff);
        }
        else
        {
          decode = 0x00;
        }
        break;
      }
    }
    break;
  case 0x06:
    User_Bytes_Sender("AT+MAC\r\n");
    status = 0x07;
    break;
  case 0x07:
    bytes = Uart_Rx_GetLen();
    status = 0x06;
    decode = 0x00;
    for (uint8_t i = 0; i < bytes; i++)
    {
      c = Uart_Rx_GetByte();
      switch (decode)
      {
      case 0x00:
        if (c == 0x2B)
        {
          decode = 0x01;
        }
        break;
      case 0x01:
        if (c == 0x4F)
        {
          decode = 0x02;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x02:
        if (c == 0x4B)
        {
          decode = 0x03;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x03:
        if (c == 0x3D)
        {
          decode = 0x04;
          Mac_Buff[0] = 0;
        }
        else
        {
          decode = 0x00;
        }
        break;
      case 0x04:
        if (c != 0x0D)
        {
          Mac_Buff[0]++;
          Mac_Buff[Mac_Buff[0]] = c;
        }
        else
        {
          decode = 0x00;
          status = 0x08;
          Cbuf_Init(Uart_RxBuff);
        }
        break;
      }
    }
    break;
  case 0x08:
    GPIOA->BRR = GPIO_BRR_BR_2;
    Task_Set_Period(TASK_ID_COMMUNICATION, 200);
    status = 0x09;
    break;
  case 0x09:
    GPIOA->BSRR = GPIO_BSRR_BS_2;
    Task_Set_Period(TASK_ID_COMMUNICATION, 3000);
    status = 0x0A;
    break;
  case 0x0A:
    Task_Init(TASK_ID_COMMUNICATION, -1, 50, Communication_Handler);
    status = 0x0B;
    break;
  default:
    break;
  }
}

void User_Packet_Sender(uint8_t rssi, uint8_t *data, uint8_t size) // 传输固定的包
{
  static uint32_t countet = 0;
  Uart_TxBuff.Packet.Header[0] = 0x54; // T
  Uart_TxBuff.Packet.Header[1] = 0x43; // C
  Uart_TxBuff.Packet.Header[2] = 0x50; // p
  Uart_TxBuff.Packet.Header[3] = 0x48; // H
  Uart_TxBuff.Packet.Header[4] = 0x45; // E
  Uart_TxBuff.Packet.Header[5] = 0x41; // A
  Uart_TxBuff.Packet.Header[6] = 0x44; // D
  Uart_TxBuff.Packet.Header[7] = 0x45; // E
  Uart_TxBuff.Packet.Header[8] = 0x52; // R
  Uart_TxBuff.Packet.Length = 0x0052;
  Uart_TxBuff.Packet.ID = (Mac_Buff[9] << 24) | (Mac_Buff[10] << 16) | (Mac_Buff[11] << 8) | Mac_Buff[12]; // lENGTH
  Uart_TxBuff.Packet.Counter = countet++;
  Uart_TxBuff.Packet.Period = 1000;
  memcpy(&Uart_TxBuff.Packet.Payload, data, size);
  Uart_TxBuff.Packet.End[0] = 0x54; // T
  Uart_TxBuff.Packet.End[1] = 0x43; // C
  Uart_TxBuff.Packet.End[2] = 0x50; // P
  Uart_TxBuff.Packet.End[3] = 0x45; // E
  Uart_TxBuff.Packet.End[4] = 0x4E; // N
  Uart_TxBuff.Packet.End[5] = 0x44; // D

  DMA1_Channel2->CCR &= ~DMA_CCR_EN; // 关闭DMA传输
  DMA1_Channel2->CMAR = (uint32_t)&Uart_TxBuff.Packet;
  DMA1_Channel2->CNDTR = 29 + size; // DMA的传输长度S
  DMA1_Channel2->CCR |= DMA_CCR_EN; // 使能DMA传输
}

void User_Bytes_Sender(char *data) // 传输字节
{
  memcpy(&Uart_TxBuff.Bytes, data, strlen(data));
  DMA1_Channel2->CCR &= ~DMA_CCR_EN; // 关闭DMA传输
  DMA1_Channel2->CMAR = (uint32_t)&Uart_TxBuff.Packet;
  DMA1_Channel2->CNDTR = strlen(data); // DMA的传输长度S
  DMA1_Channel2->CCR |= DMA_CCR_EN;    // 使能DMA传输
}

void DMA1_Channel2_3_IRQHandler(void)
{
  if ((DMA1->ISR & DMA_ISR_TCIF2) != RESET)
  {
    DMA1->IFCR = DMA_IFCR_CTCIF2;
    DMA1_Channel2->CCR &= ~DMA_CCR_EN;
  }
  if ((DMA1->ISR & DMA_ISR_TEIF2) != RESET)
  {
    DMA1->IFCR = DMA_IFCR_CTEIF2;
  }
}
